package array

//判断元素是否在切片中
func InArray(arr []string, needle string) bool {
	for _, item := range arr {
		if item == needle {
			return true
		}
	}
	return false
}

//找出长度最小的第一个数组元素
func ArrayMin(arr []string) string {
	min := ""
	minLength := 0
	for _, str := range arr {
		length := len([]rune(str))
		if length < minLength {
			minLength = length
			min = str
		}
	}
	return min
}

//反转数组
//双指针法
func ReverseStringArray(str []string) []string {
	num := len(str)
	if num == 0 {
		return []string{}
	}
	//双指针
	//找到中间位置
	mid := num / 2
	//最后一个元素
	j := num - 1
	//循环到中间位置
	for i := 0; i < mid; i++ {
		//多重赋值,左右两边元素交换
		str[i], str[j] = str[j], str[i]
		//右边指针往左移动
		j--
	}
	return str
}

//旋转数组,向右移动k个元素
//通过循环k%length , 然后循环pop push
func RotateArray(arr []string, k int) []string {
	length := len(arr)
	//取模一下
	k = k % length
	var newArr []string
	var item string
	//循环k次
	for i := 0; i < k; i++ {
		//pop出元素
		newArr, item = ArrayRPop(arr)
		newArr = ArrayLPush(newArr, item)
	}
	return newArr
}

//旋转数组,向右移动k个元素
//三步反转法
func RotateArray2(arr []string, k int) []string {
	length := len(arr)
	//取模一下
	k = k % length
	var newArr []string
	//先反转左边 , 注意这里的区间 , go切片是左闭右开 , 左边反转时 , 需要包含当前边界元素
	arrLeft := ReverseStringArray(arr[0 : k+1])
	//再反转右边
	arrRight := ReverseStringArray(arr[k+1 : length])
	newArr = append(arrLeft, arrRight...)
	//整体反转
	newArr = ReverseStringArray(newArr)
	return newArr
}

//删除排序数组中的重复项
//快慢指针暴力循环 ， 把符合要求的非重复的，计数并存到数组前面已经用过的地方
func RemoveDuplicates(nums []int) ([]int, int) {
	length := len(nums)
	i := 0
	j := 1
	count := 0
	for j < length {
		//可以暴力循环出所有的可能性
		//log.Println(nums[i], nums[j])
		//把符合要求的非重复的，计数并存储
		if nums[i] != nums[j] {
			nums[count] = nums[i]
			count++
			nums[count] = nums[j]
		}
		j++
		i++

	}
	//从旧数组中拷贝前面记录的数据到新数组
	ret := []int{}
	for i := 0; i <= count; i++ {
		ret = append(ret, nums[i])
	}
	//log.Println(nums)
	return ret, count + 1
}
